package io.lckgroup.modules.lck.utils.order;

import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 字符串工具类
 *
 * @author maj
 */
public final class StringUtil {
    /**
     * 16进制字符串序列
     */
    public static final char[] DIGIT = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

    /**
     * 字符串是为空么？
     *
     * @param str 源字符串
     * @return true:空
     */
    public static boolean stringIsNull(String str) {
        return (str == null) || (str.isEmpty());
    }

    /**
     * 16进制字符串(类似：A13B782A)转换成byte数组
     *
     * @param s 16进制字符串(类似：A13B782A)
     * @return byte数组
     */
    public static byte[] hex2byte(String s) {
        byte[] src = s.toLowerCase().getBytes();
        byte[] ret = new byte[src.length / 2];
        for (int i = 0; i < src.length; i += 2) {
            byte hi = src[i];
            byte low = src[i + 1];
            hi = (byte) ((hi >= 'a' && hi <= 'f') ?
                    0x0a + (hi - 'a') : hi - '0');
            low = (byte) ((low >= 'a' && low <= 'f') ?
                    0x0a + (low - 'a') : low - '0');
            ret[i / 2] = (byte) (hi << 4 | low);
        }
        return ret;
    }

    /**
     * byte数组转换成16进制字符串(类似：A13B782A)
     *
     * @param b byte数组
     * @return 16进制字符串(类似 ： A13B782A)
     */
    public static String byte2hex(byte[] b) {
        char[] out = new char[b.length * 2];
        for (int i = 0; i < b.length; i++) {
            byte c = b[i];
            out[i * 2] = DIGIT[(c >>> 4) & 0X0F];
            out[i * 2 + 1] = DIGIT[c & 0X0F];
        }
        return new String(out);
    }

    /**
     * 字符串转换成Unicode编码(//u)
     *
     * @param s 字符串
     * @return Unicode编码
     */
    public static String string2Unicode(String s) {
        if (stringIsNull(s)) {
            return s;
        }
        StringBuffer result = new StringBuffer();
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) >= 0x2018) {
                result.append('\\');
                result.append('u');
                String hex = Integer.toHexString(s.charAt(i));
                result.append(hex);
            } else {
                result.append(s.charAt(i));
            }
        }
        return result.toString();
    }

    /**
     * Unicode编码(//u)转换成 字符串
     *
     * @param s Unicode编码
     * @return 字符串
     */
    public static String unicode2String(String s) {
        if (stringIsNull(s)) {
            return s;
        }
        StringBuffer result = new StringBuffer();
        int start = 0;
        int end = 0;
        while ((end = s.indexOf("\\u", start)) != -1) {
            result.append(s.substring(start, end));
            start = end + 2;
            end = start + 4;
            if (end > s.length()) {
                break;
            }
            char c = (char) Integer.parseInt(s.substring(start, end), 16);
            result.append(c);
            start = end;
        }
        if (start < s.length()) {
            result.append(s.substring(start));
        }
        return result.toString();
    }

    /**
     * 把map转换成key=val&key=val的字符串。按首字母排序。
     *
     * @param params 参数map
     * @return key=val&key=val字符串
     */
    public static String map2String(Map<String, ?> params) {
        List<String> keys = new ArrayList<String>(params.keySet());
        //按字母排序
        Collections.sort(keys);
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String val = params.get(key).toString();
            sb.append(key);
            sb.append("=");
            sb.append(val);
            if (i < keys.size() - 1) {
                sb.append("&");
            }
        }
        return sb.toString();
    }

    /**
     * 生成随机的byte数组
     *
     * @param size byte数组长度
     * @return 随机的byte数组
     */
    public static byte[] genRandomByte(int size) {
        byte[] ret = new byte[size];
        new SecureRandom().nextBytes(ret);
        return ret;
    }

    /**
     * 生成当前时间字符串，格式：yyyyMMddHHmmss
     *
     * @return 当前时间字符串
     */
    public static String getCurrentTimeStr() {
        Date date = new Date();
        SimpleDateFormat form = new SimpleDateFormat("yyyyMMddHHmmss");
        return form.format(date);
    }
}